package br.usp.ime.ingpos.web.controllers;

import java.util.List;

import org.springframework.util.StringUtils;

import br.com.caelum.vraptor.Get;
import br.com.caelum.vraptor.Path;
import br.com.caelum.vraptor.Post;
import br.com.caelum.vraptor.Resource;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.Validator;
import br.com.caelum.vraptor.validator.Validations;
import br.usp.ime.ingpos.modelo.Inscricao;
import br.usp.ime.ingpos.modelo.ProcessoSeletivo;
import br.usp.ime.ingpos.modelo.TipoPerfil;
import br.usp.ime.ingpos.modelo.TipoProcessoSeletivo;
import br.usp.ime.ingpos.services.InscricaoService;
import br.usp.ime.ingpos.services.ProcessoSeletivoService;
import br.usp.ime.ingpos.web.interceptors.RestrictAccessPerfil;
import br.usp.ime.ingpos.web.interceptors.Transactional;

@Resource
public class ProcessoSeletivoController
{

    private final Result result;
    private final Validator validador;
    private final ProcessoSeletivoService processoSeletivoService;
    private final InscricaoService inscricaoService; 

    public ProcessoSeletivoController(
        final Result result,
        final Validator validador,
        final ProcessoSeletivoService processoSeletivoService,
        final InscricaoService inscricaoService)

    {
        this.result = result;
        this.validador = validador;
        this.processoSeletivoService = processoSeletivoService;
        this.inscricaoService = inscricaoService;
    }

    @Get
    @Path( "/processoSeletivo/cadastro" )
    @RestrictAccessPerfil( values = {
        TipoPerfil.PROFESSOR, TipoPerfil.CANDIDATO
    } )
    public void cadastrarProcessosSeletivos()
    {
        List<ProcessoSeletivo> processosSeletivos = processoSeletivoService.buscarTodosProcessosSeletivos();
        result.include( "processosSeletivos", processosSeletivos );
        result.include( "tipos", TipoProcessoSeletivo.getTiposProcessoSeletivo() );
    }

    @Get
    @Path( "/processoSeletivo/vigentes" )
    @RestrictAccessPerfil( values = {
        TipoPerfil.PROFESSOR, TipoPerfil.CANDIDATO
    } )
    public void processosVigentes()
    {
        List<ProcessoSeletivo> processosSeletivosVigentes = processoSeletivoService.buscarProcessosSeletivosVigentes();
        result.include( "processosSeletivosVigentes", processosSeletivosVigentes );
        result.include( "tipos", TipoProcessoSeletivo.getTiposProcessoSeletivo() );
    }

    @Post
    @Path( "/processoSeletivo/cadastro" )
    @Transactional
    public void cadastrarProcessosSeletivos(
        final ProcessoSeletivo processoSeletivo )
    {

        validador.checking( new Validations() {
            {
                that( StringUtils.hasText( processoSeletivo.getDescricao() ), "erro_visualizacao",
                    "erro_descricao_vazia" );
                that( processoSeletivo.getDataDeAbertura() != null, "data",
                    "data_invalida_abertura" );
                that( processoSeletivo.getDataLimiteDeInscricao() != null, "data",
                    "data_invalida_termino" );
                if( ( processoSeletivo.getDataDeAbertura() != null )
                    && ( processoSeletivo.getDataLimiteDeInscricao() != null ) ) {
                    that(
                        processoSeletivo.getDataLimiteDeInscricao().after(
                            processoSeletivo.getDataDeAbertura() ), "data",
                        "data_abertura_maior_termino" );
                }
            }
        } );
        validador.onErrorForwardTo( getClass() ).cadastrarProcessosSeletivos();

        processoSeletivoService.inserirProcessoSeletivo( processoSeletivo );
        result.redirectTo( getClass() ).cadastrarProcessosSeletivos();
    }

    @Get
    @Path( "/processoSeletivo/editar/{processoSeletivo.processoSeletivoId}" )
    @Transactional
    @RestrictAccessPerfil( values = {
        TipoPerfil.PROFESSOR, TipoPerfil.CANDIDATO
    } )
    public void editarProcessoSeletivo(
        final ProcessoSeletivo processoSeletivo )
    {
        result.include( "processoSeletivo",
            processoSeletivoService.getProcessoSeletivo( processoSeletivo.getProcessoSeletivoId() ) );
        result.redirectTo( getClass() ).cadastrarProcessosSeletivos();
    }

    @Get
    @Path( "/processoSeletivo/remover/{processoSeletivo.processoSeletivoId}" )
    @Transactional
    @RestrictAccessPerfil( values = {
        TipoPerfil.PROFESSOR, TipoPerfil.CANDIDATO
    } )
    public void removerProcessoSeletivo(
        final ProcessoSeletivo processoSeletivo )
    {
        processoSeletivoService.deletarProcessoSeletivo( processoSeletivo );
        result.redirectTo( getClass() ).cadastrarProcessosSeletivos();
    }
    
    @Get
    @Path( "/processoSeletivo/historico")
    @RestrictAccessPerfil( values = {
        TipoPerfil.CANDIDATO
    })
    public void historico(){
        List<ProcessoSeletivo> processosSeletivos = processoSeletivoService.buscaProcessosSeletivosFechados();
        result.include( "processosSeletivos", processosSeletivos );
    }
    
    @Post
    @Path("/processoSeletivo/historico/visualizar")
    @RestrictAccessPerfil( values = {
        TipoPerfil.CANDIDATO
    })
    public void visualizarHistorico(long processoSeletivoId){
        List<ProcessoSeletivo> processosSeletivos = processoSeletivoService.buscaProcessosSeletivosFechados();
        List<Inscricao> inscricoes = inscricaoService.getCandidatosPorProcessoSeletivo( processoSeletivoService.getProcessoSeletivo( processoSeletivoId ) );
        
        result.include( "processosSeletivos", processosSeletivos );
        result.include( "listaDeInscricoes", inscricoes );
    }      
}
